/**
 * @file bsp_linklist.c
 * @author liufeng (liufeng@injoinic.com)
 * @brief 用于WT588F02B的邻接表数据结构
 * @version 0.1
 * @date 2024-12-13
 *
 * @copyright Copyright (c) 2024  injoinic
 *
 */

#include "bsp_linklist.h"
#include "FreeRTOS.h"
#include "stdio.h"
#include "string.h"

#ifdef USE_FULL_ASSERT
#define assert_failed(char, int)              \
    do {                                      \
        printf("Error:%s,%d\r\n", char, int); \
        while (1) {                           \
        }                                     \
    } while (0)
#define assert_param(expr) \
    if (!expr)             \
    assert_failed(__FILE__, __LINE__)
#else
#define assert_param(expr) ((void)0U)
#endif

/**
 * @brief 增加一个语音结点
 * @param[in] list_handler_instance 链表handler实例
 * @param[in] voice_node 待添加的语音结点
 * @return 0：添加成功
 *         1：添加失败（指针为空、优先级不合法或者动态内存分配失败）
 */
uint8_t list_add_node(list_handler* list_handler_instance, list_voice_node* voice_node)
{
    // 判断参数合理性
    if ((list_handler_instance == NULL) || (voice_node == NULL) ||
        (voice_node->priority >= WT588F_MAX_PRIORITY)) {
        return 1;
    }

    // 根据其优先级找到该插入的链表，并找到尾结点
    uint8_t index = voice_node->priority;
    list_voice_node* tail = &(list_handler_instance->voice_list[index]);
    while (tail->next != NULL) {
        tail = tail->next;
    }

    // 新建一个结点（不建议直接挂voice_node，它可能是局部变量）
    list_voice_node* new_node = (list_voice_node*)pvPortMalloc(sizeof(list_voice_node));
    if (new_node == NULL) {
        return 1;
    }
    new_node->priority = voice_node->priority;
    new_node->volume = voice_node->volume;
    new_node->voice_address = voice_node->voice_address;

    // 将新建结点挂到末尾，并将该链表结点数量+1
    tail->next = new_node;
    new_node->previous = tail;
    new_node->next = NULL;
    list_handler_instance->amount_of_node[index] += 1;

    // 如果新增节点优先级大于当前最高优先级，更新最高优先级
    if (voice_node->priority < list_handler_instance->highest_priority) {
        list_handler_instance->highest_priority = voice_node->priority;
    }

    return 0;
}

/**
 * @brief 删除一个语音结点
 * @param[in] list_handler_instance 链表handler实例
 * @param[in] voice_node 待删除的语音结点
 * @return 0：删除成功
 *         1：删除失败（指针为空、优先级不合法或者结点不在链表中）
 */
uint8_t list_delete_node(list_handler* list_handler_instance, list_voice_node* voice_node)
{
    // 判断参数合理性
    if ((list_handler_instance == NULL) || (voice_node == NULL)) {
        return 1;
    }

    // 如果结点在链表中，删除该结点
    uint8_t index = voice_node->priority;
    if (index >= WT588F_MAX_PRIORITY) {
        return 1;
    }
    // 通过结点地址，判断结点是否在在链表中
    list_voice_node* node_temp = &(list_handler_instance->voice_list[index]);
    for (; node_temp; node_temp = node_temp->next) {
        if (node_temp == voice_node) { // 结点在链表中，删除该结点
            (voice_node->previous)->next = voice_node->next;
            if (voice_node->next) {    // 结点可能是尾结点
                (voice_node->next)->previous = voice_node->previous;
            }
            list_handler_instance->amount_of_node[index] -= 1;
            vPortFree(voice_node);

            // 当前链表为空，更新最高优先级
            for (uint8_t i = index; i < WT588F_MAX_PRIORITY; i++) {
                if (list_handler_instance->amount_of_node[i] != 0) {
                    list_handler_instance->highest_priority = i;
                    break;
                }
            }

            return 0; // 删除成功
        }
    }

    return 1; // 结点不在链表中
}

/**
 * @brief 同等优先级的结点，按语音地址升序排列（采用冒泡排序）
 * @param[in] list_handler_instance 链表handler实例
 * @param[in] priority 待排序链表的优先级
 * @return 0：排序成功
 *         1：排序失败（指针为空）
 */
uint8_t list_sort(list_handler* list_handler_instance, uint8_t priority)
{
    // 判断参数合理性
    if ((list_handler_instance == NULL) || (priority >= WT588F_MAX_PRIORITY)) {
        return 1;
    }

    // 没有结点或者只有一个结点，无需排序
    if ((list_handler_instance->amount_of_node[priority] == 0) &&
        (list_handler_instance->amount_of_node[priority] == 1)) {
        return 0;
    }

    // 链表冒泡排序，按语音地址升序排列
    uint8_t length = list_handler_instance->amount_of_node[priority];
    list_voice_node* phead = list_handler_instance->voice_list[priority].next;

    for (uint8_t i = 0; i < length - 1; i++) {
        list_voice_node* node_a = phead;       // 当前结点
        list_voice_node* node_b = phead->next; // 当前结点的后一个结点
        for (uint8_t j = 0; j < length - i - 1; j++) {
            if (node_a->voice_address > node_b->voice_address) {
                list_voice_node* node_tp = node_a->previous; // 当前结点的前一个结点
                list_voice_node* node_tn = node_b->next;     // 当前结点的后两个结点

                node_a->previous = node_b;
                node_a->next = node_tn;
                node_b->previous = node_tp;
                node_b->next = node_a;

                if (node_tp != NULL) { // a不为头结点，更新其前驱节点的后继结点
                    node_tp->next = node_b;
                }
                if (node_tn != NULL) { // b不为尾结点，更新其后继节点的前驱节点
                    node_tn->previous = node_a;
                }

                node_b = node_tn; // 注意结点迭代
            }
            else {
                // 注意结点迭代
                node_a = node_b;
                node_b = node_b->next;
            }
        }
    }

    return 0;
}

/**
 * @brief 返回具有当前最高优先级的链表的首结点地址
 * @param[in] list_handler_instance 链表handler实例
 * @return 非NULL：最高优先级的首结点地址
 *         NULL：链表为空或者参数不合理
 */
list_voice_node* list_first_node(list_handler* list_handler_instance)
{
    // 判断参数合理性
    if (list_handler_instance == NULL) {
        return NULL;
    }

    uint8_t index = list_handler_instance->highest_priority;
    list_voice_node* phead = (list_handler_instance->voice_list[index]).next;
    return phead;
}

/**
 * @brief 判断链表handler元素是否为空
 * @param[in] list_handler_instance 链表handler实例
 * @return true：链表为空或者链表地址为NULL
 *         false：链表不为空
 */
bool list_is_empty(list_handler* list_handler_instance)
{
    if (list_handler_instance == NULL) {
        return true;
    }

    for (uint8_t i = 0; i < WT588F_MAX_PRIORITY; i++) {
        if (list_handler_instance->amount_of_node[i] != 0) {
            return false; // 有元素，则不为空
        }
    }
    return true;
}

/**
 * @brief 链表handler构造函数
 * @param[in] list_handler_instance 链表handler实例
 * @return 0：构造成功
 *         1：构造失败
 */
uint8_t list_handler_construct(list_handler* list_handler_instance)
{
    if (list_handler_instance == NULL) {
        return 1;
    }

    memset(list_handler_instance->amount_of_node, 0, sizeof(uint8_t) * WT588F_MAX_PRIORITY);
    memset(list_handler_instance->voice_list, 0, sizeof(list_voice_node) * WT588F_MAX_PRIORITY);
    list_handler_instance->current_priority = 15; // 初始优先级设为15
    list_handler_instance->highest_priority = 15;

    // 函数指针挂载
    list_handler_instance->pf_add_node = list_add_node;
    list_handler_instance->pf_delete_node = list_delete_node;
    list_handler_instance->pf_sort = list_sort;
    list_handler_instance->pf_first_node = list_first_node;
    list_handler_instance->pf_is_empty = list_is_empty;

    return 0;
}
